home *** CD-ROM | disk | FTP | other *** search
- MODULE tfile;
- __IMP_SWITCHES__
- #ifdef HM2
- #ifdef __LONG_WHOLE__
- (*$!i+: Modul muss mit $i- uebersetzt werden! *)
- (*$!w+: Modul muss mit $w- uebersetzt werden! *)
- #else
- (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
- (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
- #endif
- #endif
- (* Test fuer Module 'file' und 'dir'.
- *
- * Das ist beileibe kein vollstaendiger Test - wenn also bei irgendeiner
- * Prozedur das OK verweigert wird, ist bei der Anpassung auf jeden Fall
- * ein Fehler unterlaufen, ein OK heisst aber lediglich, dass keine
- * offensichtlichen Fehler existieren.
- *
- * hk, 18-Dez-93
- *)
-
- VAL_INTRINSIC
- CAST_IMPORT
-
- FROM SYSTEM IMPORT
- (* PROC *) ADR;
-
- FROM PORTAB IMPORT
- (* CONST*) NULL;
-
- FROM types IMPORT
- (* CONST*) PATHMAX,
- (* TYPE *) PathName, offT, StrPtr;
-
- IMPORT e;
-
- FROM file IMPORT
- (* CONST*) StdoutFileNo, StderrFileNo, fOK, oACCMODE, oRDONLY, oWRONLY, oRDWR,
- sIRWXU, MINHANDLE,
- (* TYPE *) FileModes, modeT, AccessModes, AccessMode, OpenModes,
- OpenMode, SeekMode, FDFlags, FDFlag, FcntlCmd, FcntlArg,
- (* PROC *) creat, open, fcntl, close, read, write, lseek, dup, dup2, umask,
- chmod, utime, access;
-
- FROM term IMPORT
- (* PROC *) isatty;
-
- FROM dir IMPORT
- (* PROC *) getcwd, mkdir, chdir, rmdir, unlink, rename;
-
- FROM cstr IMPORT
- (* PROC *) strerror;
-
- FROM Terminal IMPORT
- (* PROC *) Read, Write, WriteString, WriteLn;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- VAR
- handle : INTEGER;
- newout : INTEGER;
- oldout : INTEGER;
- name : PathName;
- done : BOOLEAN;
- ch : CHAR;
- oldmask : modeT;
- buf : ARRAY [0..100] OF CHAR;
- farg : FcntlArg;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- PROCEDURE ASSERT ((* EIN/ -- *) test : BOOLEAN;
- (* EIN/ -- *) msg : ARRAY OF CHAR): BOOLEAN;
-
- VAR errstr : ARRAY [0..40] OF CHAR;
-
- BEGIN
- WriteString(msg);
- IF test THEN
- WriteString(" -- OK"); WriteLn;
- e.errno := 0;
- RETURN(TRUE);
- ELSE
- strerror(e.errno, errstr); (* Fehler im Klartext ausgeben *)
- WriteString(" **failed**:: "); WriteString(errstr); WriteLn;
- e.errno := 0;
- Read(ch); (* Auf Tastendruck warten *)
- RETURN(FALSE);
- END;
- END ASSERT;
-
- (*===========================================================================*)
-
- BEGIN
- e.errno := 0;
-
- (* Schreibgeschuetzte Datei erzeugen *)
- handle := creat("XYZ12345.TMP", modeT{sIRUSR});
- IF ASSERT(handle>=0,'handle <- creat("XYZ12345.TMP",modeT{sIRUSR})') THEN
- done := ASSERT(close(handle)=0,'close(handle)');
- END;
-
- (* Datei muss vorhanden sein, aber weder Schreib- noch Ausfuehrberechtigung *)
- done := ASSERT(access("XYZ12345.TMP",fOK)=0,'access("XYZ12345.TMP",fOK)');
- done := ASSERT(access("XYZ12345.TMP",AccessMode{wOK})<0,'access("XYZ12345.TMP",AccessMode{wOK})<0');
- done := ASSERT(access("XYZ12345.TMP",AccessMode{xOK})<0,'access("XYZ12345.TMP",AccessMode{xOK})<0');
- WriteLn;
-
- (* Schreibschutz aufheben, Schreibberechtigung muss vorhanden sein *)
- IF ASSERT(chmod("XYZ12345.TMP",modeT{sIRUSR,sIWUSR})=0,'chmod("XYZ12345.TMP",modeT{sIRUSR,sIWUSR})') THEN
- done := ASSERT(access("XYZ12345.TMP",AccessMode{wOK})=0,'access("XYZ12345.TMP",AccessMode{wOK})');
- END;
- WriteLn;
-
- (* Datei umbenennen, alter Name darf nicht mehr vorhanden sein, aber der neue *)
- IF ASSERT(rename("XYZ12345.TMP","XYZ54321.TMP")=0,'rename("XYZ12345.TMP","XYZ54321.TMP")') THEN
- done := ASSERT(access("XYZ54321.TMP",fOK)=0,'access("XYZ54321.TMP",fOK)');
- done := ASSERT(access("XYZ12345.TMP",fOK)<0,'access("XYZ12345.TMP",fOK)<0');
- END;
- WriteLn;
-
- (* Datei loeschen, darf nicht mehr vorhanden sein *)
- IF ASSERT(unlink("XYZ54321.TMP")=0,'unlink("XYZ54321.TMP")') THEN
- done := ASSERT(access("XYZ54321.TMP",fOK)<0,'access("XYZ54321.TMP",fOK)<0');
- END;
- WriteLn;
-
- (* Ausfuehrbare Datei erzeugen, Ausfuehrberechtigung muss vorhanden sein *)
- handle := creat("XYZ12345.TTP",sIRWXU);
- IF ASSERT(handle>=0,'handle <- creat("XYZ12345.TTP",sIRWXU)') THEN
- done := ASSERT(close(handle)=0,'close(handle)');
- done := ASSERT(access("XYZ12345.TTP",AccessMode{xOK})=0,'access("XYZ12345.TTP",AccessMode{xOK})');
- done := ASSERT(unlink("XYZ12345.TTP")=0,'unlink("XYZ12345.TTP")');
- END;
- WriteLn;
-
- (* Dateierstellungsmaske setzen, sodass keine Schreibberechtigung erzeugt
- * werden kann. Datei erzeugen, muss vorhanden, aber schreibgeschuetzt sein.
- * Datei loeschen, alte Maske wiederherstellen.
- *)
- oldmask := umask(modeT{sIWUSR});
- done := ASSERT(TRUE,'oldmask <- umask(modeT{sIWUSR})');
- handle := creat("XYZ12345.TMP", sIRWXU);
- IF ASSERT(handle>=0,'handle <- creat("XYZ12345.TMP",sIRWXU)') THEN
- done := ASSERT(close(handle)=0,'close(handle)');
- done := ASSERT(access("XYZ12345.TMP",fOK)=0,'access("XYZ12345.TMP",fOK)');
- done := ASSERT(access("XYZ12345.TMP",AccessMode{wOK})<0,'access("XYZ12345.TMP",AccessMode{wOK})<0');
- done := ASSERT(chmod("XYZ12345.TMP",modeT{sIRUSR,sIWUSR})=0,'chmod("XYZ12345.TMP",modeT{sIRUSR,sIWUSR})');
- done := ASSERT(unlink("XYZ12345.TMP")=0,'unlink("XYZ12345.TMP")');
- END;
- done := ASSERT(umask(oldmask)=modeT{sIWUSR},'umask(oldmask)=modeT{sIWUSR}');
- WriteLn;
-
- (* Zweite Kennung fuer STDOUT erzeugen und wieder freigeben *)
- handle := dup(StdoutFileNo);
- IF ASSERT(handle>StdoutFileNo,'handle <- dup(StdoutFileNo)') THEN
- done := ASSERT(close(handle)=0,'close(handle)');
- END;
-
- (* STDOUT auf STDERR umlenken, Umlenkung wieder rueckgaengig machen *)
- newout := dup(StderrFileNo);
- oldout := dup(StdoutFileNo);
- IF ASSERT(oldout>StdoutFileNo,'oldout <- dup(StdoutFileNo)')
- AND ASSERT(newout>StderrFileNo,'newout <- dup(StderrFileNo)')
- THEN
- (* Wenn die Ausgabe des Programms auf eine Datei umgelenkt wurde,
- * erscheint die Ausgabe der folgenden Zeile trotzdem auf dem
- * Bildschirm, da 'StdoutFileNo' umgelenkt ist.
- * Das passiert natuerlich nur, wenn 'WriteString' auf "GEMDOS"-Kanal 1
- * ausgibt.
- *)
- IF ASSERT(dup2(newout,StdoutFileNo)>=StdoutFileNo,'dup2(newout,StdoutFileNo)') THEN
- (* Hier wird die Umlenkung wieder rueckgaengig gemacht: *)
- done := ASSERT(dup2(oldout,StdoutFileNo)>=StdoutFileNo,'dup2(oldout,StdoutFileNo)');
- done := ASSERT(close(oldout)=0,'close(oldout)');
- done := ASSERT(close(newout)=0,'close(newout)');
- END;
- END;
- WriteLn;
-
- (* Aktuelles Arbeitsverzeichnis ermitteln *)
- IF ASSERT(getcwd(CAST(StrPtr,ADR(name)),PATHMAX+1)<>NULL,'getcwd(name,PATHMAX+1)') THEN
- WriteString(': name ="'); WriteString(name); Write('"'); WriteLn;
- END;
-
- (* Neues Verzeichnis erzeugen mit Suchberechtigung. Verzeichnis muss vorhanden
- * sein und suchen erlauben. Ins neue Verzeichnis wechseln und neues Arbeits-
- * verzeichnis ermitteln. Wieder zurueck ins alte Arbeitsverzeichnis.
- * Neues Verzeichnis wieder loeschen, darf nicht mehr vorhanden sein.
- *)
- IF ASSERT(mkdir("XYZ12345.DIR",sIRWXU)=0,'mkdir("XYZ12345.DIR",sIRWXU)') THEN
- done := ASSERT(access("XYZ12345.DIR",fOK)=0,'access("XYZ12345.DIR",fOK)');
- done := ASSERT(access("XYZ12345.DIR",AccessMode{xOK})=0,'access("XYZ12345.DIR",AccessMode{xOK})');
- IF ASSERT(chdir("XYZ12345.DIR")=0,'chdir("XYZ12345.DIR")') THEN
- IF ASSERT(getcwd(CAST(StrPtr,ADR(name)),PATHMAX+1)<>NULL,'getcwd(name,PATHMAX+1)') THEN
- WriteString(': name ="'); WriteString(name); Write('"'); WriteLn;
- END;
- done := ASSERT(chdir("..")=0,'chdir("..")');
- END;
- IF ASSERT(rmdir("XYZ12345.DIR")=0,'rmdir("XYZ12345.DIR")') THEN
- done := ASSERT(access("XYZ12345.DIR",fOK)<0,'access("XYZ12345.DIR",fOK)<0');
- END;
- END;
- WriteLn;
-
- (* Datei erzeugen und 10 Zeichen hineinschreiben. Datei nicht mit "creat()"
- * erzeugen, da dann die Datei im ``Nur-Schreib-Modus'' geoeffnet wird, und
- * nicht gelesen werden kann (GEMDOS prueft das nicht ab, aber MiNT!).
- *)
- buf := "12345678901234567890";
- WriteString('buf <- "12345678901234567890"'); WriteLn;
- handle := open("XYZ12345.TMP", oRDWR+OpenMode{oCREAT}, modeT{sIRUSR,sIWUSR});
- IF ASSERT(handle>=0,'handle <- open("XYZ12345.TMP",oRDWR+OpenMode{oCREAT},modeT{sIRUSR,sIWUSR})') THEN
- done := ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10)=10');
- END;
-
- (* Schreibzeiger hinter das Ende der Datei positionieren und weitere 10 Bytes
- * schreiben. Nochmal verlaengern und ein Byte schreiben; die aktuelle
- * Position muss mit der Verlaengerung uebereinstimmen. Vom Dateiende 100
- * Bytes zurueckgehen, um zu sehen, ob die Datei tatsaechlich verlaengert
- * wurde.
- *)
- IF ASSERT(INT(lseek(handle,1005,SeekCur))=1015,'lseek(handle,1005,SeekCur)=1015') THEN
- done := ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10)=10');
- done := ASSERT(INT(lseek(handle,2999,SeekSet))=2999,'lseek(handle,2999,SeekSet)=2999');
- IF ASSERT(INT(lseek(handle,0,SeekCur))=2999,'lseek(handle,2999,SeekCur)=2999') THEN
- done := ASSERT(INT(write(handle,ADR(buf),1))=1,'write(handle,ADR(buf),1)=1');
- done := ASSERT(INT(lseek(handle,-100,SeekEnd))=2900,'lseek(handle,-100,SeekEnd)=2900');
- END;
- END;
-
- (* Lesezeiger auf die Position, an der zum zweitenmal geschrieben wurde, ein
- * paar Bytes lesen und mit den geschriebenen vergleichen. Datei schliessen.
- *)
- IF ASSERT(INT(lseek(handle,1010,SeekSet))=1010,'lseek(handle,1010,SeekSet)=1010') THEN
- IF ASSERT(INT(read(handle,ADR(buf),10))=10,'read(handle,ADR(buf),10))=10') THEN
- done := ASSERT((buf[3]=0C)AND(buf[4]=0C)AND(buf[5]='1')AND(buf[6]='2'),
- "buf[3..6] = 0C,0C,'1','2'");
- END;
- END;
- done := ASSERT(close(handle)=0,'close(handle)');
- WriteLn;
-
- (* Feststellen, ob CON: oder STDOUT auf Datei umgelenkt wurden. *)
- WriteString("isatty(-1): ");
- IF isatty(-1) > 0 THEN
- WriteString("ja");
- ELSE
- WriteString("nein");
- END;
- WriteLn;
- WriteString("isatty(StdoutFileNo): ");
- IF isatty(StdoutFileNo) > 0 THEN
- WriteString("ja");
- ELSE
- WriteString("nein");
- END;
- WriteLn;
- WriteLn;
-
-
- (* Vorhandene Testdatei mit Flag O_APPEND oeffnen. Kennung darf nicht
- * fuer ein Terminal gehalten werden; die Anfangsposition muss sich
- * trotz O_APPEND am Anfang der Datei befinden. 10 Bytes schreiben,
- * die aktuelle Position muss sich 10 Bytes hinter dem urspruenglichen
- * Dateiende befinden. An den Dateianfang zurueck und nochmal 10 Bytes
- * schreiben, die akt. Position muss sich 20 bytes hinter dem urspr.
- * Dateiende befinden.
- *)
- handle := open("XYZ12345.TMP",oRDWR+OpenMode{oAPPEND},modeT{});
- IF ASSERT(handle>=0,'handle <- open("XYZ12345.TMP",oRDWR+OpenMode{oAPPEND},modeT{})') THEN
- done := ASSERT(isatty(handle)<=0,'isatty(handle)<=0');
- IF ASSERT(INT(lseek(handle,0,SeekCur))=0,'lseek(handle,0,SeekCur)=0') THEN
- done := ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10)=10');
- IF ASSERT(INT(lseek(handle,0,SeekCur))=3010,'lseek(handle,0,SeekCur)=3010') THEN
- done:=ASSERT(INT(lseek(handle,0,SeekSet))=0,'lseek(handle,0,SeekSet)=0');
- done:=ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10)=10');
- done:=ASSERT(INT(lseek(handle,0,SeekCur))=3020,'lseek(handle,0,SeekCur)=3020');
- END;
- END;
- END;
- done := ASSERT(close(handle)=0,'close(handle)');
- WriteLn;
-
- (* Vorhandene Testdatei zum Schreiben oeffnen ohne weitere Flags.
- * Flags der Dateikennung erfragen, das 'FdCloExec'-Flag darf nicht gesetzt
- * sein. Flag setzen und pruefen, ob es gesetzt wurde.
- * Flags des Dateibeschreibungsblocks abfragen, der Zugriffsmodus muss
- * oWRONLY sein, und keine weiteren Flags duerfen gesetzt sein.
- * 10 Bytes schreiben, die aktuelle Position muss 10 sein.
- * Zugriffsmodus auf oRDWR setzen und oAPPEND setzen. Flags wieder erfragen,
- * der Zugriffsmodus muss unveraendert oWRONLY sein, aber oAPPEND muss
- * gesetzt sein. Wieder 10 Bytes schreiben, die Datei muss um 10 Bytes
- * verlaengert worden sein.
- *
- * Datei schliessen und loeschen fuer nachfolgenden Test.
- *)
- handle := open("XYZ12345.TMP",oWRONLY+OpenMode{},modeT{});
- IF ASSERT(handle>=0,'handle <- open("XYZ12345.TMP",oWRONLY+OpenMode{},modeT{})') THEN
- IF ASSERT(fcntl(handle,fGETFD,farg)=0,'fcntl(handle,fGETFD,fdflags)=0') THEN
- done:=ASSERT(NOT(FdCloExec IN farg.fdflags),'NOT(FdCloExec IN fdflags)');
- END;
- farg.fdflags := FDFlag{FdCloExec};
- WriteString('fdflags <- FDFlag{FdCloExec}'); WriteLn;
- IF ASSERT(fcntl(handle,fSETFD,farg)=0,'fcntl(handle,fSETFD,fdflags)=0') THEN
- IF ASSERT(fcntl(handle,fGETFD,farg)=0,'fcntl(handle,fGETFD,fdflags)=0') THEN
- done:=ASSERT(FdCloExec IN farg.fdflags,'FdCloExec IN fdflags');
- END;
- END;
- IF ASSERT(fcntl(handle,fGETFL,farg)=0,'fcntl(handle,fGETFL,mode)=0') THEN
- done:=ASSERT(farg.mode=oWRONLY,'farg.mode = oWRONLY');
- END;
- done := ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10)=10');
- done := ASSERT(INT(lseek(handle,0,SeekCur))=10,'lseek(handle,0,SeekCur)=10');
- farg.mode := oRDWR + OpenMode{oAPPEND};
- WriteString('mode <- oRDWR + OpenMode{oAPPEND}'); WriteLn;
- IF ASSERT(fcntl(handle,fSETFL,farg)=0,'fcntl(handle,fSETFL,mode)=0') THEN
- IF ASSERT(fcntl(handle,fGETFL,farg)=0,'fcntl(handle,fGETFL,mode)=0') THEN
- done:=ASSERT(farg.mode*oACCMODE=oWRONLY,'mode * oACCMODE = oWRONLY');
- done:=ASSERT(oAPPEND IN farg.mode,'oAPPEND IN mode');
- END;
- done := ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10)=10');
- done := ASSERT(INT(lseek(handle,0,SeekCur))=3030,'lseek(handle,0,SeekCur)=3030');
- END;
- END;
- done := ASSERT(close(handle)=0,'close(handle)');
- done := ASSERT(unlink("XYZ12345.TMP")=0,'unlink("XYZ12345.TMP")');
- WriteLn;
-
- (* Ohne Flag O_CREAT darf Datei beim Oeffnen nicht angelegt werden. *)
- handle := open("XYZ12345.TMP",oRDWR,modeT{sIRUSR,sIWUSR});
- IF NOT ASSERT(handle<0,'open("XYZ12345.TMP",oRDWR,modeT{sIRUSR,sIWUSR})<0') THEN
- handle := close(handle);
- END;
-
- (* Datei exklusiv neu anlegen mit Schreibberechtigung. Ein paar Bytes
- * schreiben und wieder schliessen.
- * Nochmal versuchen, exklusiv anzulegen, Datei darf nicht mehr neu angelegt
- * oder gekuerzt werden, da schon vorhanden.
- *)
- handle := open("XYZ12345.TMP",oRDWR+OpenMode{oCREAT,oEXCL},modeT{sIRUSR,sIWUSR});
- IF ASSERT(handle>=0,'handle <- open("XYZ12345.TMP",oRDWR+OpenMode{oCREAT,oEXCL},modeT{sIRUSR,sIWUSR})') THEN
- done := ASSERT(INT(write(handle,ADR(buf),10))=10,'write(handle,ADR(buf),10))=10');
- done := ASSERT(close(handle)=0,'close(handle)');
- END;
- handle := open("XYZ12345.TMP",oRDWR+OpenMode{oCREAT,oEXCL},modeT{sIWUSR});
- IF NOT ASSERT((handle<0)AND(e.errno=e.EEXIST),'open("XYZ12345.TMP",oRDWR+OpenMode{oCREAT,oEXCL},modeT{sIWUSR})<0') THEN
- handle := close(handle);
- END;
- WriteLn;
-
- (* Datei mit Flag O_CREAT oeffnen, darf dabei aber nicht gekuerzt werden,
- * deshalb Dateilaenge feststellen und wieder schliessen.
- * Datei mit Flag O_TRUNC oeffnen, muss dabei auf Null Bytes gekuerzt werden,
- * deshalb Dateilaenge feststellen und wieder schliessen.
- * Testdatei loeschen.
- *)
- handle := open("XYZ12345.TMP", oRDWR+OpenMode{oCREAT}, modeT{});
- IF ASSERT(handle>=0,'handle <- open("XYZ12345.TMP",oRDWR+OpenMode{oCREAT},modeT{})') THEN
- done := ASSERT(INT(lseek(handle,0,SeekCur))=0,'lseek(handle,0,SeekCur)=0');
- done := ASSERT(INT(lseek(handle,0,SeekEnd))=10,'lseek(handle,0,SeekEnd))=10');
- done := ASSERT(close(handle)=0,'close(handle)');
- END;
- handle := open("XYZ12345.TMP", oRDWR+OpenMode{oTRUNC}, modeT{});
- IF ASSERT(handle>=0,'handle <- open("XYZ12345.TMP",oRDWR+OpenMode{oTRUNC},modeT{})') THEN
- done := ASSERT(INT(lseek(handle,0,SeekEnd))=0,'lseek(handle,0,SeekEnd)=0');
- done := ASSERT(close(handle)=0,'close(handle)');
- done := ASSERT(unlink("XYZ12345.TMP")=0,'unlink("XYZ12345.TMP")');
- END;
- WriteLn;
-
- Read(ch);
- END tfile.
-